package com.auxgroup.hr.front.service.performance.impl;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.auxgroup.hr.front.commons.utils.WebServiceClient;
import com.auxgroup.hr.front.commons.utils.WebServiceUtils;
import com.auxgroup.hr.front.commons.vo.DocQueRespVO;
import com.auxgroup.hr.front.commons.vo.DocSecRespVO;
import com.auxgroup.hr.front.commons.vo.ExamInfoRespVO;
import com.auxgroup.hr.front.commons.vo.QueItemReqVO;
import com.auxgroup.hr.front.dao.domain.PsCEvQstResult;
import com.auxgroup.hr.front.dao.domain.PsCEvQstResultPrimary;
import com.auxgroup.hr.front.dao.domain.PsCEvaDocEvlt;
import com.auxgroup.hr.front.dao.domain.PsCEvaDocEvltPrimary;
import com.auxgroup.hr.front.dao.domain.PsCEvaDocSecV;
import com.auxgroup.hr.front.dao.domain.PsCEvaDocVw;
import com.auxgroup.hr.front.dao.domain.PsCEvaDocVwPrimary;
import com.auxgroup.hr.front.dao.domain.PsCEvaShtGdT;
import com.auxgroup.hr.front.dao.domain.PsCEvaShtQstM;
import com.auxgroup.hr.front.dao.repository.PsCEvQstResultRepository;
import com.auxgroup.hr.front.dao.repository.PsCEvaDocEvltRepository;
import com.auxgroup.hr.front.dao.repository.PsCEvaDocSecVRepository;
import com.auxgroup.hr.front.dao.repository.PsCEvaDocVwRepository;
import com.auxgroup.hr.front.dao.repository.PsCEvaShtGdtRepository;
import com.auxgroup.hr.front.dao.repository.PsCEvaShtQstMRepository;
import com.auxgroup.hr.front.service.performance.AssessService;
import com.auxgroup.hr.front.ws.SoapXmlBuild;

/** 
 * @author lvliuhao 
 * @version 创建时间：2018年8月20日 下午4:50:06 
 * 类说明 
 */
@Service("assessService")
public class AssessServiceImpl implements AssessService {
	@Autowired
	private PsCEvaDocVwRepository psCEvaDocVwRepository;
	
	@Autowired
	private PsCEvaDocEvltRepository psCEvaDocEvltRepository;
	
	@Autowired
	private PsCEvaDocSecVRepository psCEvaDocSecVRepository;
	
	@Autowired
	private PsCEvQstResultRepository psCEvQstResultRepository;
	
	@Autowired
	private PsCEvaShtQstMRepository psCEvaShtQstMRepository;
	
	@Autowired
	private PsCEvaShtGdtRepository psCEvaShtGdtRepository;
	
	@Value("${ws.processService.approve.address}")
	private String processURL;
	
	@Value("${ws.processService.evaPoint.soapAction}")
	private String evaPointSoapAction;


	@Override
	public List<PsCEvaDocVw> getEvaPersons(String oprid,String sheetId,String queryKey) {
		Specification<PsCEvaDocVw> spec = new Specification<PsCEvaDocVw>() {
			@Override
			public Predicate toPredicate(Root<PsCEvaDocVw> root, CriteriaQuery<?> query,
					CriteriaBuilder builder) {
				Predicate opridEqul = builder.equal(root.get("oprid"), oprid);
				Predicate sheetIdEqul = builder.equal(root.get("cEvaSheetId"),sheetId);
				Predicate all = builder.and(opridEqul,sheetIdEqul);
				if(StringUtils.isNotBlank(queryKey)){
					return builder.and(all,builder.like(root.get("name"), "%"+queryKey+"%"));
				}
				return builder.and(all);
			}
		};
		return psCEvaDocVwRepository.findAll(spec,new Sort(Direction.ASC, "cEvaSheetId","cSeqno","seqno"));
	}

	@Override
	public PsCEvaDocEvlt getEvaDocEvlt(String docid, String role,
			String evaluator) {
		PsCEvaDocEvltPrimary pk = new PsCEvaDocEvltPrimary();
		pk.setcEvaDocId(docid);
		pk.setcEvaluateRole(role);
		pk.setcEvaluator(evaluator);
		return psCEvaDocEvltRepository.findOne(pk);
	}

	@Override
	public PsCEvaDocVw getEvaPer(PsCEvaDocVwPrimary primary) {
		return psCEvaDocVwRepository.findOne(primary);
	}


	@Override
	public ExamInfoRespVO getExamInfo(PsCEvaDocVw evaDoc) {
		ExamInfoRespVO respVO = new ExamInfoRespVO();
		respVO.setName(evaDoc.getName());
		respVO.setDept(evaDoc.getRsFullName());
		respVO.setEmplid(evaDoc.getEmplid());
		respVO.setJobDescr(evaDoc.getJobcodeDescr());
		respVO.setTitle(evaDoc.getTitle());
		if(StringUtils.isNotBlank(evaDoc.getComments())){
			respVO.setComments(evaDoc.getComments().replaceAll("\n", "<br/>").replaceAll(" ", "&nbsp;"));//替换换行
		}
		respVO.setDocid(evaDoc.getcEvaDocId());
		respVO.setEvaluator(evaDoc.getcEvaluator());
		respVO.setRole(evaDoc.getcEvaluateRole());
		buildExamInfo(respVO,evaDoc);
		return respVO;
	}
	
	
	private void buildExamInfo(ExamInfoRespVO respVO,PsCEvaDocVw evaDoc){
		//区段号集合
		List<PsCEvaDocSecV> secSeqs = psCEvaDocSecVRepository.getSecSeqs(evaDoc.getcEvaDocId(), evaDoc.getcEvaluateRole(), evaDoc.getcEvaluator());
		if(secSeqs==null||secSeqs.isEmpty()){
			respVO.setDocSecs(new ArrayList<DocSecRespVO>());
			return;
		}
		//题目ID集合
		List<String[]> queIds = psCEvQstResultRepository.getSecQues(evaDoc.getcEvaDocId(), evaDoc.getcEvaluateRole(), evaDoc.getcEvaluator());
		if(queIds==null||queIds.isEmpty()){
			respVO.setDocSecs(new ArrayList<DocSecRespVO>());
			return;
		}
		List<DocSecRespVO> secRespVOs = new ArrayList<DocSecRespVO>();
		DocSecRespVO secRespVo;
		List<DocQueRespVO> queRespVOs;
		Map<String, List<String>> queAndSecIds = changeQuesID(queIds);
		for (int i = 0; i < secSeqs.size(); i++) {
			secRespVo = new DocSecRespVO();
			secRespVo.setSeqnbr(String.valueOf(secSeqs.get(i).getcEvaSectionSeq()));
			if(StringUtils.isNotBlank(secSeqs.get(i).getcEvaSection())){
				secRespVo.setTitle(capitalNumber1(i+1)+secSeqs.get(i).getcEvaSection().replaceAll("\n", "<br/>").replaceAll(" ", "&nbsp;"));
			}
			queRespVOs = new ArrayList<DocQueRespVO>();
			DocQueRespVO queRespVo;
			List<PsCEvaShtQstM> ques = getQuestions(evaDoc.getcEvaSheetId(),queAndSecIds.get(String.valueOf(secSeqs.get(i).getcEvaSectionSeq())));
			for (int j = 0; j < ques.size(); j++) {
				queRespVo = new DocQueRespVO();
				if(StringUtils.isNotBlank(ques.get(j).getDescr())){
					queRespVo.setDescr((j+1)+"."+ques.get(j).getDescr().replaceAll("\n", "<br/>").replaceAll(" ", "&nbsp;"));
				}
				if(StringUtils.isNotBlank(ques.get(j).getDescrlong())){
					queRespVo.setDetailDescr(ques.get(j).getDescrlong().replaceAll("\n", "<br/>").replaceAll(" ", "&nbsp;"));
				}
				queRespVo.setQueid(ques.get(j).getcEvaQuestion());
				queRespVo.setSecSeq(String.valueOf(secSeqs.get(i).getcEvaSectionSeq()));
				if(StringUtils.isNotBlank(ques.get(j).getDescrlong1())){
					queRespVo.setDescription(ques.get(j).getDescrlong1().replaceAll("\n", "<br/>").replaceAll(" ", "&nbsp;"));
				}
				queRespVo.setMethod(ques.get(j).getcEvaMethod());
				List<PsCEvaShtGdT> gds = psCEvaShtGdtRepository.getGdsBySheetAndQueid(evaDoc.getcEvaSheetId(), ques.get(j).getcEvaQuestion());
				//获取已填结果。
				PsCEvQstResultPrimary primary = new PsCEvQstResultPrimary();
				primary.setcEvaDocId(evaDoc.getcEvaDocId());
				primary.setcEvaluateRole(evaDoc.getcEvaluateRole());
				primary.setcEvaluator(evaDoc.getcEvaluator());
				primary.setcEvaQuestion(ques.get(j).getcEvaQuestion());
				primary.setcEvaSectionSeq(secSeqs.get(i).getcEvaSectionSeq());
				PsCEvQstResult qstResult = psCEvQstResultRepository.findOne(primary);
				queRespVo.setQueGds(changeGdMap(gds));
				if(qstResult!=null){
					if("C".equals(queRespVo.getMethod())){
						queRespVo.setAnswer(qstResult.getcEvaQstResult2());
					}else{
						queRespVo.setAnswer(qstResult.getcEvaQstResult1().split("@"));
					}
				}
				queRespVOs.add(queRespVo);
			}
			secRespVo.setQues(queRespVOs);
			secRespVOs.add(secRespVo);
		}
		respVO.setDocSecs(secRespVOs);
	}
	
	
	
	private List<PsCEvaShtQstM> getQuestions(String sheetid,List<String> queIds){
		Specification<PsCEvaShtQstM> query = new Specification<PsCEvaShtQstM>() {
			@Override
			public Predicate toPredicate(Root<PsCEvaShtQstM> root,
					CriteriaQuery<?> query, CriteriaBuilder builder) {
				Predicate sheetIdEq = builder.equal(root.get("cEvaSheetId"), sheetid);//sheetid等于
				Predicate cEvaQuestionIn = root.get("cEvaQuestion").in(queIds); //绑定状态
				return builder.and(sheetIdEq,cEvaQuestionIn);
			}
		};
		return psCEvaShtQstMRepository.findAll(query,new Sort(Direction.ASC, "cEvaQuestion"));
	}

	
	private Map<String, List<String>> changeQuesID(List<String[]> ids){
		Map<String, List<String>> QueandSecIds = new HashMap<String, List<String>>();
		String seq;
		List<String> queIds;
		for (Object[] id : ids) {
			seq = id[0].toString();
			if(!QueandSecIds.containsKey(seq)){
				queIds = new ArrayList<String>();
				queIds.add(id[1].toString());
				QueandSecIds.put(seq, queIds);
			}else{
				QueandSecIds.get(seq).add(id[1].toString());
			}
		}
		return QueandSecIds;
	}
	
	private List<Map<String, Object>> changeGdMap(List<PsCEvaShtGdT> gds){
		List<Map<String, Object>> GdMaps = new ArrayList<Map<String,Object>>();
		Map<String, Object> gd;
		for (PsCEvaShtGdT gdt : gds) {
			gd = new HashMap<String, Object>();
			gd.put("item", gdt.getcEvaGrade()+"."+gdt.getcEvaGradeDesc());
			gd.put("score", String.valueOf(gdt.getcGradeDigit()));
			gd.put("grade", gdt.getcEvaGrade());
			GdMaps.add(gd);
		}
		return GdMaps;
	}
	
	
	
	private String capitalNumber1(int nu){
		switch(nu){
		case 1:
			return "一.";
		case 2:
			return "二.";
		case 3:
			return "三.";
		case 4:
			return "四.";
		case 5:
			return "五.";
		case 6:
			return "六.";
		case 7:
			return "七.";
		case 8:
			return "八.";
		case 9:
			return "九.";
		default:
			return "十.";
		}
	}


	@Override
	public void saveScore(List<QueItemReqVO> reqVos,String docid,String role,String evaluator) {
		if(reqVos==null||reqVos.isEmpty()){
			return;
		}
		PsCEvQstResultPrimary primary;
		for (QueItemReqVO reqvo : reqVos) {
			primary = new PsCEvQstResultPrimary();
			primary.setcEvaDocId(docid);
			primary.setcEvaluateRole(role);
			primary.setcEvaluator(evaluator);
			primary.setcEvaQuestion(reqvo.getQueid());
			primary.setcEvaSectionSeq(new BigDecimal(reqvo.getSecSeq()));
			PsCEvQstResult result = psCEvQstResultRepository.findOne(primary);
			if(result!=null){
				//A：单选题；B：多选题；C：开放性题
				if(reqvo.getMethod().equals("C")){
					result.setcEvaQstResult2(reqvo.getSelected());
				}else{
					if(reqvo.getMethod().equals("B")){
						String[] len = reqvo.getSelected().split("@");
						if(len!=null&&len.length>0){
							result.setcEvaPoint(new BigDecimal(reqvo.getScore()).divide(new BigDecimal(len.length)));
						}
					}else{
						result.setcEvaPoint(new BigDecimal(reqvo.getScore()));
					}
					result.setcEvaQstResult1(reqvo.getSelected());
				}
			}
			psCEvQstResultRepository.save(result);
		}
	}

	@Override
	public String handleScoreByWebService(String docid) {
		StringBuilder soapXml = new StringBuilder();
		SoapXmlBuild.buildEvaPoint(soapXml,docid);
		String responXml = WebServiceClient.doPostSoap(processURL, soapXml.toString(), evaPointSoapAction);
		Map<String, String> result = WebServiceUtils.handleEvaPointRespXml(responXml,"C_EVA_POINT_RSP");
		if(result!=null){
			if("Y".equals(result.get("FLAG"))){
				return result.get("FLAG");
			}
			return result.get("COMMENTS");
		}
		return "总分计算错误";
	}


	@Override
	public void saveDocEvlt(String docid, String role, String evaluator,String oprid) {
		PsCEvaDocEvltPrimary primary = new PsCEvaDocEvltPrimary();
		primary.setcEvaDocId(docid);
		primary.setcEvaluateRole(role);
		primary.setcEvaluator(evaluator);
		PsCEvaDocEvlt docEvlt = psCEvaDocEvltRepository.findOne(primary);
		docEvlt.setcEvaDocStatus("C");
		String point = psCEvQstResultRepository.getSumPoint(docid, role, evaluator);
		docEvlt.setcEvaPoint(new BigDecimal(point));
		docEvlt.setHrsRowUpdOprid(oprid);
		docEvlt.setHrsRowUpdDttm(new Timestamp(System.currentTimeMillis()));
		psCEvaDocEvltRepository.save(docEvlt);
	}
}
 